"use client";
import type { FC } from "react";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import TemplateVarPanel, { PanelTitle, VarOpBtnGroup } from "../value-panel";
import s from "./style.module.css";
import {
  AppInfoComp,
  ChatBtn,
  EditBtn,
  FootLogo,
  PromptTemplate,
} from "./massive-component";
import type { AppInfo, PromptConfig } from "@/types/app";
import Toast from "@/app/components/base/toast";
import Select from "@/app/components/base/select";
import { DEFAULT_VALUE_MAX_LEN } from "@/config";
import { APP_INFO } from "@/config";

// regex to match the {{}} and replace it with a span
const regex = /\{\{([^}]+)\}\}/g;

export type IWelcomeProps = {
  conversationName: string;
  hasSetInputs: boolean;
  isPublicVersion: boolean;
  siteInfo: AppInfo;
  promptConfig: PromptConfig;
  onStartChat: (inputs: Record<string, any>) => void;
  canEditInputs: boolean;
  savedInputs: Record<string, any>;
  onInputsChange: (inputs: Record<string, any>) => void;
};

const Welcome: FC<IWelcomeProps> = ({
  conversationName,
  hasSetInputs,
  isPublicVersion,
  siteInfo,
  promptConfig,
  onStartChat,
  canEditInputs,
  savedInputs,
  onInputsChange,
}) => {
  const { t } = useTranslation();
  const hasVar = promptConfig?.prompt_variables?.length > 0;
  const [isFold, setIsFold] = useState<boolean>(true);
  const [inputs, setInputs] = useState<Record<string, any>>(
    (() => {
      if (hasSetInputs) return savedInputs;

      const res: Record<string, any> = {};
      if (promptConfig) {
        promptConfig.prompt_variables.forEach((item) => {
          res[item.key] = "";
        });
      }
      return res;
    })(),
  );
  useEffect(() => {
    if (!savedInputs) {
      const res: Record<string, any> = {};
      if (promptConfig) {
        promptConfig.prompt_variables.forEach((item) => {
          res[item.key] = "";
        });
      }
      setInputs(res);
    } else {
      setInputs(savedInputs);
    }
  }, [savedInputs]);

  const highLightPromoptTemplate = (() => {
    if (!promptConfig) return "";
    const res = promptConfig.prompt_template.replace(regex, (match, p1) => {
      return `<span class='text-gray-800 font-bold'>${inputs?.[p1] ? inputs?.[p1] : match}</span>`;
    });
    return res;
  })();

  const { notify } = Toast;
  const logError = (message: string) => {
    notify({ type: "error", message, duration: 3000 });
  };

  const renderHeader = () => {
    return (
      <div className="absolute top-0 left-0 right-0 flex items-center justify-between border-b border-gray-100 mobile:h-12 tablet:h-16 px-8 bg-white">
        <div className="text-gray-900">{conversationName}</div>
      </div>
    );
  };

  const renderInputs = () => {
    return (
      <div className="space-y-3">
        {promptConfig.prompt_variables.map((item) => (
          <div
            className="tablet:flex items-start mobile:space-y-2 tablet:space-y-0 mobile:text-xs tablet:text-sm"
            key={item.key}
          >
            <label
              className={`flex-shrink-0 flex items-center tablet:leading-9 mobile:text-gray-700 tablet:text-gray-900 mobile:font-medium pc:font-normal ${s.formLabel}`}
            >
              {item.name}
            </label>
            {item.type === "select" && (
              <Select
                className="w-full"
                defaultValue={inputs?.[item.key]}
                onSelect={(i) => {
                  setInputs({ ...inputs, [item.key]: i.value });
                }}
                items={(item.options || []).map((i) => ({ name: i, value: i }))}
                allowSearch={false}
                bgClassName="bg-gray-50"
              />
            )}
            {item.type === "string" && (
              <input
                placeholder={`${item.name}${!item.required ? `(${t("app.variableTable.optional")})` : ""}`}
                value={inputs?.[item.key] || ""}
                onChange={(e) => {
                  setInputs({ ...inputs, [item.key]: e.target.value });
                }}
                className={
                  "w-full flex-grow py-2 pl-3 pr-3 box-border rounded-lg bg-gray-50"
                }
                maxLength={item.max_length || DEFAULT_VALUE_MAX_LEN}
              />
            )}
            {item.type === "paragraph" && (
              <textarea
                className="w-full h-[104px] flex-grow py-2 pl-3 pr-3 box-border rounded-lg bg-gray-50"
                placeholder={`${item.name}${!item.required ? `(${t("app.variableTable.optional")})` : ""}`}
                value={inputs?.[item.key] || ""}
                onChange={(e) => {
                  setInputs({ ...inputs, [item.key]: e.target.value });
                }}
              />
            )}
            {item.type === "number" && (
              <input
                type="number"
                className="block w-full p-2 text-gray-900 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 "
                placeholder={`${item.name}${!item.required ? `(${t("appDebug.variableTable.optional")})` : ""}`}
                value={inputs[item.key]}
                onChange={(e) => {
                  onInputsChange({ ...inputs, [item.key]: e.target.value });
                }}
              />
            )}
          </div>
        ))}
      </div>
    );
  };

  const canChat = () => {
    const inputLens = Object.values(inputs).length;
    const promptVariablesLens = promptConfig?.prompt_variables.length;
    const emptyInput =
      inputLens < promptVariablesLens ||
      Object.values(inputs).filter((v) => v === "").length > 0;
    if (emptyInput) {
      logError(t("app.errorMessage.valueOfVarRequired"));
      return false;
    }
    return true;
  };

  const handleChat = () => {
    //todo: 临时去掉
    // if (!canChat()) return;

    onStartChat(inputs);
  };

  const renderNoVarPanel = () => {
    if (isPublicVersion) {
      return (
        <div>
          <AppInfoComp siteInfo={siteInfo} />
          <TemplateVarPanel
            isFold={false}
            header={
              <>
                <PanelTitle
                  title={t("app.chat.publicPromptConfigTitle")}
                  className="mb-1"
                />
                <PromptTemplate html={highLightPromoptTemplate} />
              </>
            }
          >
            <ChatBtn onClick={handleChat} />
          </TemplateVarPanel>
        </div>
      );
    }
    // private version
    return (
      <TemplateVarPanel
        isFold={false}
        header={<AppInfoComp siteInfo={siteInfo} />}
      >
        <ChatBtn onClick={handleChat} />
      </TemplateVarPanel>
    );
  };

  const renderVarPanel = () => {
    return (
      <TemplateVarPanel
        isFold={false}
        header={<AppInfoComp siteInfo={siteInfo} />}
      >
        {renderInputs()}
        <ChatBtn
          className="mt-3 mobile:ml-0 tablet:ml-[128px]"
          onClick={handleChat}
        />
      </TemplateVarPanel>
    );
  };

  const renderVarOpBtnGroup = () => {
    return (
      <VarOpBtnGroup
        onConfirm={() => {
          if (!canChat()) return;

          onInputsChange(inputs);
          setIsFold(true);
        }}
        onCancel={() => {
          setInputs(savedInputs);
          setIsFold(true);
        }}
      />
    );
  };

  const renderHasSetInputsPublic = () => {
    if (!canEditInputs) {
      return (
        <TemplateVarPanel
          isFold={false}
          header={
            <>
              <PanelTitle
                title={t("app.chat.publicPromptConfigTitle")}
                className="mb-1"
              />
              <PromptTemplate html={highLightPromoptTemplate} />
            </>
          }
        />
      );
    }

    return (
      <TemplateVarPanel
        isFold={isFold}
        header={
          <>
            <PanelTitle
              title={t("app.chat.publicPromptConfigTitle")}
              className="mb-1"
            />
            <PromptTemplate html={highLightPromoptTemplate} />
            {isFold && (
              <div className="flex items-center justify-between mt-3 border-t border-indigo-100 pt-4 text-xs text-indigo-600">
                <span className="text-gray-700">
                  {t("app.chat.configStatusDes")}
                </span>
                <EditBtn onClick={() => setIsFold(false)} />
              </div>
            )}
          </>
        }
      >
        {renderInputs()}
        {renderVarOpBtnGroup()}
      </TemplateVarPanel>
    );
  };

  const renderHasSetInputsPrivate = () => {
    if (!canEditInputs || !hasVar) return null;

    return (
      <TemplateVarPanel
        isFold={isFold}
        header={
          <div className="flex items-center justify-between text-indigo-600">
            <PanelTitle
              title={
                !isFold
                  ? t("app.chat.privatePromptConfigTitle")
                  : t("app.chat.configStatusDes")
              }
            />
            {isFold && <EditBtn onClick={() => setIsFold(false)} />}
          </div>
        }
      >
        {renderInputs()}
        {renderVarOpBtnGroup()}
      </TemplateVarPanel>
    );
  };

  const renderHasSetInputs = () => {
    if ((!isPublicVersion && !canEditInputs) || !hasVar) return null;

    return (
      <div className="pt-[88px] mb-5">
        {isPublicVersion
          ? renderHasSetInputsPublic()
          : renderHasSetInputsPrivate()}
      </div>
    );
  };

  return (
    <div className="relative mobile:min-h-[48px] tablet:min-h-[64px]">
      {hasSetInputs && renderHeader()}
      <div className="mx-auto pc:w-[794px] max-w-full mobile:w-full px-3.5">
        {/*  Has't set inputs  */}
        {!hasSetInputs && (
          <div className="mobile:pt-[72px] tablet:pt-[128px] pc:pt-[200px]">
            {hasVar ? renderVarPanel() : renderNoVarPanel()}
          </div>
        )}

        {/* Has set inputs */}
        {hasSetInputs && renderHasSetInputs()}

        {/* foot */}
        {!hasSetInputs && (
          <div className="mt-4 flex justify-between items-center h-8 text-xs text-gray-400">
            {siteInfo.privacy_policy ? (
              <div>
                {t("app.chat.privacyPolicyLeft")}
                <a
                  className="text-gray-500"
                  href={siteInfo.privacy_policy}
                  target="_blank"
                >
                  {t("app.chat.privacyPolicyMiddle")}
                </a>
                {t("app.chat.privacyPolicyRight")}
              </div>
            ) : (
              <div></div>
            )}
            <a
              className="flex items-center pr-3 space-x-3"
              href="https://dify.ai/"
              target="_blank"
            >
              <span className="uppercase">{t("app.chat.powerBy")}</span>
              {/* <FootLogo /> */}
              <span className="text-gray-400">{APP_INFO.copyright}</span>
            </a>
          </div>
        )}
      </div>
    </div>
  );
};

export default React.memo(Welcome);
